package com.zut.chat.service;

import com.zut.chat.entity.User;
import com.zut.chat.mapper.UserMapper;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

import static com.zut.chat.entity.table.UserTableDef.USER;

/**
 * 用户服务类
 */
@Service
public class UserService extends ServiceImpl<UserMapper, User> {

    /**
     * 根据会话ID查找用户
     */
    public User findBySessionId(String sessionId) {
        return getOne(QueryWrapper.create()
                .where(USER.SESSION_ID.eq(sessionId)));
    }

    /**
     * 检查昵称是否已被使用
     */
    public boolean isNicknameExists(String nickname) {
        return count(QueryWrapper.create()
                .where(USER.NICKNAME.eq(nickname))) > 0;
    }

    /**
     * 检查昵称是否被其他用户使用
     */
    public boolean isNicknameExistsByOtherUser(String nickname, String sessionId) {
        return count(QueryWrapper.create()
                .where(USER.NICKNAME.eq(nickname))
                .and(USER.SESSION_ID.ne(sessionId))) > 0;
    }

    /**
     * 创建或更新用户
     */
    public User createOrUpdateUser(String sessionId, String nickname) {
        User existingUser = findBySessionId(sessionId);
        
        if (existingUser != null) {
            // 检查昵称是否被其他用户使用
            if (isNicknameExistsByOtherUser(nickname, sessionId)) {
                throw new RuntimeException("昵称已被使用，请选择其他昵称");
            }
            
            // 更新现有用户
            existingUser.setNickname(nickname);
            existingUser.setOnline(true);
            existingUser.setLastActiveTime(LocalDateTime.now());
            updateById(existingUser);
            return existingUser;
        } else {
            // 检查昵称是否已被使用
            if (isNicknameExists(nickname)) {
                throw new RuntimeException("昵称已被使用，请选择其他昵称");
            }
            
            // 创建新用户，默认为普通用户类型
            User newUser = User.builder()
                    .nickname(nickname)
                    .sessionId(sessionId)
                    .online(true)
                    .userType(User.UserType.NORMAL)
                    .createTime(LocalDateTime.now())
                    .lastActiveTime(LocalDateTime.now())
                    .build();
            save(newUser);
            return newUser;
        }
    }

    /**
     * 设置用户离线
     */
    public void setUserOffline(String sessionId) {
        User user = findBySessionId(sessionId);
        if (user != null) {
            user.setOnline(false);
            user.setLastActiveTime(LocalDateTime.now());
            updateById(user);
        }
    }

    /**
     * 获取在线用户列表
     */
    public List<User> getOnlineUsers() {
        return list(QueryWrapper.create()
                .where(USER.ONLINE.eq(true))
                .orderBy(USER.LAST_ACTIVE_TIME.desc()));
    }

    /**
     * 获取在线用户数量
     */
    public long getOnlineUserCount() {
        return count(QueryWrapper.create()
                .where(USER.ONLINE.eq(true)));
    }

    /**
     * 根据昵称搜索在线用户
     */
    public List<User> searchOnlineUsers(String nickname) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .where(USER.ONLINE.eq(true));
        
        if (nickname != null && !nickname.trim().isEmpty()) {
            queryWrapper.and(USER.NICKNAME.like("%" + nickname.trim() + "%"));
        }
        
        return list(queryWrapper.orderBy(USER.LAST_ACTIVE_TIME.desc()));
    }

    /**
     * 检查用户是否为管理员
     */
    public boolean isAdmin(String sessionId) {
        User user = findBySessionId(sessionId);
        return user != null && User.UserType.ADMIN.equals(user.getUserType());
    }

    /**
     * 设置用户为管理员
     */
    public boolean setUserAsAdmin(String sessionId) {
        User user = findBySessionId(sessionId);
        if (user != null) {
            user.setUserType(User.UserType.ADMIN);
            updateById(user);
            return true;
        }
        return false;
    }

    /**
     * 强制用户下线（管理员踢出功能）
     */
    public boolean forceUserOffline(String targetSessionId) {
        User user = findBySessionId(targetSessionId);
        if (user != null) {
            user.setOnline(false);
            user.setLastActiveTime(LocalDateTime.now());
            updateById(user);
            return true;
        }
        return false;
    }

    /**
     * 获取所有用户列表
     */
    public List<User> getAllUsers() {
        return list(QueryWrapper.create()
                .orderBy(USER.CREATE_TIME.desc()));
    }

    /**
     * 根据昵称搜索用户
     */
    public List<User> searchUsersByNickname(String nickname) {
        return list(QueryWrapper.create()
                .where(USER.NICKNAME.like("%" + nickname + "%"))
                .orderBy(USER.CREATE_TIME.desc()));
    }

    /**
     * 根据用户类型获取用户列表
     */
    public List<User> getUsersByType(User.UserType userType) {
        return list(QueryWrapper.create()
                .where(USER.USER_TYPE.eq(userType))
                .orderBy(USER.CREATE_TIME.desc()));
    }

    /**
     * 获取管理员数量
     */
    public long getAdminCount() {
        return count(QueryWrapper.create()
                .where(USER.USER_TYPE.eq(User.UserType.ADMIN)));
    }

    /**
     * 禁言用户
     */
    public boolean banUser(String sessionId, String reason, LocalDateTime expireTime) {
        User user = findBySessionId(sessionId);
        if (user != null && !User.UserType.ADMIN.equals(user.getUserType())) {
            user.setBanned(true);
            user.setBanReason(reason);
            user.setBanExpireTime(expireTime);
            return updateById(user);
        }
        return false;
    }

    /**
     * 解除禁言
     */
    public boolean unbanUser(String sessionId) {
        User user = findBySessionId(sessionId);
        if (user != null) {
            user.setBanned(false);
            user.setBanReason(null);
            user.setBanExpireTime(null);
            return updateById(user);
        }
        return false;
    }

    /**
     * 检查并自动解除过期的禁言
     */
    public void checkAndUnbanExpiredUsers() {
        LocalDateTime now = LocalDateTime.now();
        List<User> expiredBannedUsers = list(QueryWrapper.create()
                .where(USER.BANNED.eq(true))
                .and(USER.BAN_EXPIRE_TIME.isNotNull())
                .and(USER.BAN_EXPIRE_TIME.le(now)));

        for (User user : expiredBannedUsers) {
            user.setBanned(false);
            user.setBanReason(null);
            user.setBanExpireTime(null);
            updateById(user);
        }
    }

    /**
     * 获取被禁言的用户列表
     */
    public List<User> getBannedUsers() {
        return list(QueryWrapper.create()
                .where(USER.BANNED.eq(true))
                .orderBy(USER.CREATE_TIME.desc()));
    }

    public void resetOnlineUsers() {
        update(
                User.builder().online(false).build(),
                QueryWrapper.create()
                        .where(USER.ONLINE.eq(true))
        );
    }
}
